<template>
    <el-dialog
        v-model="dialogVisible"
        @close="closeDialog"
        :title="`${title}${maxTitle}`"
        :close-on-click-modal="false"
        width="490px"
    >
        <div class="pb10">
            <el-input v-model="keyword" @keyup.enter="mdSearch" @clear="mdSearch" :placeholder="placeholder" clearable>
                <template #suffix>
                    <el-icon @click="mdSearch" class="pointer">
                        <Search/>
                    </el-icon>
                </template>
            </el-input>
        </div>

        <el-table
            ref="multipleTableRef"
            :empty-text="emptyText"
            :data="searchListData"
            :row-key="getRowKeys"
            style="width: 100%;"
            height="300"
            @selection-change="handleSelectionChange"
            v-loading="tableLoading"
            element-loading-background="rgba(0,0,0,0)"
        >
            <el-table-column :reserve-selection="true" type="selection" width="30"/>
            <el-table-column
                v-for="row in columns"
                :key="row.value"
                :property="row.value"
                :label="row.label"
                :min-width="row.minWidth"
                show-overflow-tooltip
            />
        </el-table>

        <template #footer>
            <ul class="f-c-b pl5">
                <li>
                    <el-checkbox
                        v-if="!isMax"
                        :disabled="disLoading"
                        v-model="checkAll"
                        :indeterminate="indeterminate"
                        @change="handleCheckAll"
                    >
                        全选
                    </el-checkbox>
                </li>
                <li>
                    <el-button @click="cancelDialog">取消</el-button>
                    <el-button type="primary" :loading="disLoading" :disabled="disLoading" @click="onDialog">确认</el-button>
                </li>
            </ul>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
    import { ref, computed, watch, PropType } from "vue";
    import { ElMessage, ElTable } from "element-plus";
    import { Search } from "@element-plus/icons-vue"
    import { getRestfulV2MallCoupons } from "@/assets/api";

    const props = defineProps({
        modelValue: {
            type: Boolean,
            default: false,
        },
        title: {
            type: String,
            default: '选择奖券'
        },
        placeholder: {
            type: String,
            default: '搜索优惠券ID、优惠券名称、优惠券来源'
        },
        keyName: {
            type: String,
            default: '',
        },
        params: {
            type: Object,
            default: () => {
                return {}
            }
        },
        columns: {
            type: Array as PropType<{ value: string, label: string, minWidth: number }[]>,
            default: () => {
                return [
                    { value: 'id', label: '优惠券ID', minWidth: 80 },
                    { value: 'name', label: '优惠券名称', minWidth: 130 },
                    { value: 'source', label: '优惠券来源', minWidth: 130 },
                    { value: 'left_num', label: '剩余库存', minWidth: 80 },
                ]
            }
        },
        ids: {
            type: Array,
            default: () => {
                return []
            },
        },
        concatData: {
            type: Array,
            default: () => {
                return []
            },
        },
        max: {
            type: Number,
            default: 0
        },
    })

    // 是否设置最大可选数量
    const isMax = computed(() => {
        return props.max > 0;
    })
    // 选中数量
    const doneNumber = computed(() => {
        return checkListData.value.length;
    })
    const maxTitle = computed(() => {
        const text: string = `已选${doneNumber.value}`;
        return `${isMax.value ? `(${text}/${props.max})` : `(${text})`}`
    })

    const emit = defineEmits(['update:modelValue', 'change']);
    let dialogVisible = ref<boolean>(false);// 显示弹窗
    let emptyText = ref<string>('');// 接口请求加载中
    let keyword = ref<string>('');// 搜索
    let listData: ObjValueAny[] = [];// 列表所有数据
    let searchListData = ref<ObjValueAny[]>([]);// 列表显示数据
    let checkListData = ref<ObjValueAny[]>([]);// 已选择数据
    let disLoading = ref<boolean>(false);// 按钮禁用
    let tableLoading = ref<boolean>(false);// 列表loading

    const getRowKeys = (row: ObjValueAny) => {
        return row.id;
    }

    const handleSelectionChange = (val: ObjValueAny[]) => {
        if (val.length > props.max && isMax.value) {
            ElMessage.closeAll();
            ElMessage.warning(`最多可选 ${props.max} 个`);
            let delRow = val.pop();
            multipleTableRef.value!.toggleRowSelection(delRow, false);
        } else {
            checkListData.value = val;
        }
        getCheckAll();
    }

    // 全选
    const multipleTableRef = ref<InstanceType<typeof ElTable>>();
    const handleCheckAll = (bool: boolean) => {
        if (bool) {
            multipleTableRef.value!.toggleAllSelection();
        } else {
            for (let delRow of searchListData.value) {
                multipleTableRef.value!.toggleRowSelection(delRow, false);
            }
        }
    }
    const checkAll = ref<boolean>(false);// 是否全选
    const indeterminate = ref<boolean>(false);// 有选中 未全选

    const getCheckAll = () => {
        const checkIds = getSearchCheckListData();
        checkAll.value = !!(searchListData.value?.length && searchListData.value?.length === checkIds?.length);
        indeterminate.value = !!(searchListData.value?.length && checkIds?.length && searchListData.value?.length !== checkIds?.length)
    }
    // 搜索后显示列表的选中项 非全部选中项
    const getSearchCheckListData = () => {
        const listDict: ObjValueAny = {};
        for (let row of searchListData.value) {
            listDict[row.id] = true;
        }
        const checkIds = [];
        for (let row of checkListData.value) {
            if (listDict[row.id]) checkIds.push(row.id);
        }
        return checkIds;
    }
    // 确认选择
    const onDialog = () => {
        onChange(checkListData.value);
    }
    // emit 事件
    const onChange = (list: ObjValueAny[] = []) => {
        const value = list.map((row: ObjValueAny) => {
            return row.id
        });
        emit('change', list, value, props.keyName);
        cancelDialog();
    }
    // 关闭弹窗
    const cancelDialog = () => {
        dialogVisible.value = false;
    }
    // 关闭弹窗
    const closeDialog = () => {
        cancelDialog();
        emit('update:modelValue', dialogVisible.value)
    }

    const mdSearch = async () => {
        tableLoading.value = true;
        searchListData.value = await getDataList();
        getCheckAll();
        getEmptyText();
    }

    const getEmptyText = () => {
        emptyText.value = searchListData.value.length ? '' : '暂无数据';
    }

    // 优惠券列表
    const getDataList = (params: ObjValueAny = {}): Promise<ObjValueAny[]> => {
        return new Promise((resolve) => {
            getRestfulV2MallCoupons({
                keyword: keyword.value,
                page: 1,
                per_page: 6000,
                ...props.params,
                ...params
            }, { noRepeat: 1 }).then((resp: ObjValueAny) => {
                if (resp.code === 200) {
                    resp.data = resp.data.concat(props.concatData);
                } else {
                    ElMessage.error(resp.msg);
                }
                disLoading.value = false;
                tableLoading.value = false;
                resolve(resp?.data || []);
            })
        })
    }

    // 删除表头全选元素
    const removeTableAllCheckDom = () => {
        setTimeout(() => {
            const clearDom = document.querySelectorAll('.el-table__header-wrapper .el-table__header .el-table-column--selection .el-checkbox__input');
            Array.from(clearDom).forEach((row) => {
                row.remove()
            })
        })
    }

    watch(() => props.modelValue, async (newVal: boolean) => {
        dialogVisible.value = newVal;
        if (newVal) {
            removeTableAllCheckDom();
            disLoading.value = true;
            emptyText.value = '加载中...';
            listData = await getDataList();
            searchListData.value = listData;
            for (let i = 0; i < listData.length; i++) {
                const row: ObjValueAny = listData[i];
                if (props.ids.includes(row.id)) {
                    checkListData.value.push(row);
                    multipleTableRef.value!.toggleRowSelection(row, undefined)
                }
            }
        } else {
            // 定时器 防止 弹出未完全关闭时 肉眼弹窗可见数据变化
            setTimeout(() => {
                keyword.value = '';
                checkListData.value = [];
                multipleTableRef.value!.clearSelection();
                listData = [];
                searchListData.value = [];
            }, 100);
        }
        getCheckAll();
        getEmptyText();
    })
</script>